
var vue = new Vue({
    el: "#app",

    data: {
        env: ENV,
        ENV_FILE,
        ENV_SERVER,
        ENV_ELECTRON,
        ENV_TAURI,

        // ---------------------------------------------
        // search-bar
        searchList: [],
        searchKeyword: "",
        searchShowed: false,
        searchActiveIndex: 0,
        searchedClassify: "",
        
        // ---------------------------------------------
        bookmarkList: [],

        menuIndex: 0,

        bookmarkVisible: false,
        bookmarkLevel: 1,
        bookmarkDoing: "edit",  // add
        bookmarkEditing: {
            id: "",
            type: 2,
            parentId: 0,
            title: "",
            url: "",
            icon: "",
            orders: 10,
            hidden: 1
        },

        // ---------------------------------------------
        // toast
        toastVisible: false,
        toastContent: "",

        // ---------------------------------------------
        // hidden
        hiddened: true,
        hiddenClickCount: 0,
        hiddenTimeout: null,

        // ---------------------------------------------
    },

    computed: {
        username() {
            return getUsername() || "username"
        },
        
        menuList() {
            return this.bookmarkList
                .filter(bookmark => bookmark.parentId == 0)
                .sort((m, n) => m.orders - n.orders)
                .map(item => {
                    item.groupList = this.bookmarkList.filter(m => m.parentId == item.id)
                        .sort((m, n) => m.orders - n.orders);
                    return item;
                });
        },

        currentMenu() {
            return this.menuIndex < this.menuList.length ? this.menuList[this.menuIndex] : {};
        },

        groupList() {
            var currentMenu = this.currentMenu;

            return this.bookmarkList.filter(bookmark => bookmark.parentId == currentMenu.id)
                .sort((m, n) => m.orders - n.orders);
        },
    },

    methods: {
        // -----------------------------------------------------------
        search(e) {
            this.searchActiveIndex = 0;
            this.searchShowed = true;
            this.filterSearch();
        },
        closeSearch() {
            this.searchShowed = false;
            this.searchList = [];
            this.searchKeyword = "";
        },

        // 获取搜索列表
        filterSearch() {
            this.searchList = this.bookmarkList.filter(bookmark => bookmark.type == 2)
                .filter(bookmark => {
                    // 隐藏的
                    if (this.hiddened && bookmark.hidden != 1) return false;

                    if (this.searchKeyword) {
                        return bookmark.title.toLowerCase().search(this.searchKeyword) >= 0
                    }
                    return true;
                })
                .sort((m, n) => m.title < n.title);
        },

        // 鼠标选择
        searchSelect(bookmark) {
            if (!bookmark) return;

            window.location.hash = "";
            this.menuIndex = this.menuList.findIndex(menu => menu.id == bookmark.parentId);
            this.$nextTick(() => {
                window.location.hash = "#" + bookmark.title;
                this.closeSearch();
            })
        },
        // 使用enter选择
        searchEnterSelect() {
            if (this.searchShowed && this.searchList.length > 0) {
                this.searchSelect(this.searchList[this.searchActiveIndex]);
            }
        },
        // 键盘上下移动获取项
        stepSearchList(step=1) {
            if (this.searchShowed && Array.isArray(this.searchList)) {
                var searchListLength = this.searchList.length;

                var newStep = this.searchActiveIndex + step;
                this.searchActiveIndex = newStep < 0 ? 0 : (newStep >= searchListLength ? searchListLength - 1 : newStep);
            }
        },

        // -----------------------------------------------------------
        setFavicon(force = false) {
            if (force || !this.bookmarkEditing.icon) {
                this.bookmarkEditing.icon = this.getFavicon(this.bookmarkEditing.url);
            }
        },

        // -----------------------------------------------------------
        findBookmarkByParentId(parentId) {
            return this.bookmarkList.filter(bookmark => bookmark.parentId == parentId).sort((a, b) => a.orders - b.orders);
        },
        
        getBookmarkList() {
            return apis.getAllBookmark().then(res => {
                this.bookmarkList = res || [];
            })
        },

        // -----------------------------------------------------------
        validBookmark(bookmark) {
            return bookmark.title;
        },
        addBookmark() {
            if (!this.validBookmark(this.bookmarkEditing)) { return; }

            this.bookmarkEditing.orders = parseInt(this.bookmarkEditing.orders)
            delete this.bookmarkEditing.id;
            return apis.addBookmark(this.bookmarkEditing).then(() => { 
                this.toast("add success");
                this.getBookmarkList();
                this.bookmarkVisible = false;
            })
        },
        saveBookmark() {
            if (!this.validBookmark(this.bookmarkEditing)) { return; }

            this.bookmarkEditing.orders = parseInt(this.bookmarkEditing.orders)
            return apis.updateBookmark(this.bookmarkEditing).then(() => { 
                this.toast("update success");
                this.getBookmarkList();
                this.bookmarkVisible = false;
            })
        },
        removeBookmark() {
            if (confirm("Confirm delete?")) {
                apis.deleteBookmark(this.bookmarkEditing.id).then(() => { 
                    this.toast("delted success");
                    this.getBookmarkList();
                    this.bookmarkVisible = false;
                })
            }
        },

        initPopForm() {
            this.bookmarkEditing.id = "";
            this.bookmarkEditing.parentId = 0;
            this.bookmarkEditing.title = "";
            this.bookmarkEditing.type = 1;
            this.bookmarkEditing.orders = 10;
            this.bookmarkEditing.hidden = 1;
            this.bookmarkEditing.url = "";
            this.bookmarkEditing.icon = "";
        },
       
        showAddCompany() {
            this.initPopForm();
            this.bookmarkLevel = 1;
            this.bookmarkVisible = true;
            this.bookmarkDoing = "add";
            this.bookmarkEditing.type = 1;
        },
        showEditCompany(record) {
            this.initPopForm();
            this.bookmarkLevel = 1;
            this.bookmarkVisible = true;
            this.bookmarkDoing = "edit";
            this.bookmarkEditing = this.deepcopy(record);
            this.bookmarkEditing.type = 1;
        },

        showAddGroup(menuId) {
            this.initPopForm();
            this.bookmarkLevel = 2;
            this.bookmarkVisible = true;
            this.bookmarkEditing.parentId = menuId || this.currentMenu.id;
            this.bookmarkDoing = "add";
            this.bookmarkEditing.type = 2;
        },
        showEditGroup(record) {
            this.bookmarkLevel = 2;
            this.bookmarkVisible = true;
            this.bookmarkDoing = "edit";
            this.bookmarkEditing = this.deepcopy(record);
            this.bookmarkEditing.type = 2;
        },

        showAddBookmark(groupId) {
            this.initPopForm();
            this.bookmarkLevel = 3;
            this.bookmarkVisible = true;
            this.bookmarkDoing = "add";
            this.bookmarkEditing.parentId = groupId;
            this.bookmarkEditing.type = 3;
        },
        showEditBookmark(record) {
            this.bookmarkLevel = 3;
            this.bookmarkVisible = true;
            this.bookmarkDoing = "edit";
            this.bookmarkEditing = this.deepcopy(record);
            this.bookmarkEditing.type = 3;
        },

        saveToLocalhost() {
            apis.saveDb().then(() => {
                this.toast("Save Success");
            })
        },

        translateImgToBase64(cb) {
            if (this.bookmarkEditing.url.search("http") >= 0) {
                getImgBase64(this.bookmarkEditing.url, (base64) => {
                    this.bookmarkEditing.url = base64;
                    cb();
                });
                return;
            }

            cb();
        },

        // ----------------------------------------------------
        // common
        deepcopy(obj) {
            if (typeof obj != 'object' && !Array.isArray(obj)) {
                return {};
            }

            return JSON.parse(JSON.stringify(obj));
        },

        // -------------------------------
        // toast
        toast(content) {
            this.toastContent = content;
            this.toastVisible = true;

            setTimeout(() => {
                this.toastVisible = false;
            }, 1500);
        },

        // 找到网址favicon
        getFavicon(url) {
            var reg = /^(https?:\/\/)?([a-zA-Z0-9.]+)/;
            var math = url.match(reg);
            var protocol = math && math[1] ? math[1] : "https://"
            var host = math ? math[2] : "";

            if (host == "") {
                return this.getDefaultFavicon();
            }

            // favicon
            var fav = "favicon.ico";
            return protocol + host + "/" + fav;
        },

        getDefaultFavicon() {
            return "../static/images/web.png"
        },

        // ----------------------------------------------------
        // hidden
        showHidder() {
            this.hiddenClickCount++;

            if (this.hiddenClickCount == 3) {
                this.hiddened = false;
            }

            clearTimeout(this.hiddenTimeout);
            this.hiddenTimeout = setTimeout(() => {
                this.hiddenClickCount = 0;
            }, 2000);
        },

        // ----------------------------------------------------
        // events
        initEvents(e) {
            if (e.shiftKey) {
                switch(e.keyCode) {
                    case 81:
                        // Q: add company
                        this.showAddCompany(1);
                        break;

                    case 65:
                        // A: add group
                        this.showAddGroup(1);
                        break;
                  
                    case 90:
                        // Z: add Bookmark
                        this.showAddBookmark(1);
                        break;

                    case 76:
                        // l save
                        this.saveToLocalhost();
                        break;

                    case 86:
                        // v
                        this.hiddened = true;
                        break;
                    case 75:
                        // k
                        this.showHidder();
                        break;
                }
            }
        },

        bindEvents() {
            this.keyEventHandle = this.initEvents.bind(this);

            this.keyUpEvents = e => {
                if (e.keyCode == 27) {
                    if (this.bookmarkVisible) {
                        this.bookmarkVisible = false;
                    }
                }
            }

            this.keyDownHandle = (e) => {
                switch(e.keyCode) {
                    case 27:
                        // escape
                        this.searchShowed = false;
                        break;
                    case 13:
                        // enter
                        this.searchEnterSelect();
                        break;
                    case 38:
                        // upload
                        this.stepSearchList(-1);
                        break;
                    case 40:
                        // download
                        this.stepSearchList(1);
                        break;
                        
                }
            }

            document.body.addEventListener("keypress", this.keyEventHandle);
            document.body.addEventListener("keyup", this.keyUpEvents);
            document.body.addEventListener("keydown", this.keyDownHandle);
        },

        unbindEvents() {
            document.body.removeEventListener("keypress", this.keyEventHandle);
            document.body.removeEventListener("keyup", this.keyUpEvents);
            document.body.removeEventListener("keydown", this.keyDownHandle);
        }
    },

    created() {
        this.getBookmarkList();
        this.bindEvents();
    },

    beforeDestroy() {
        this.unbindEvents();
    },

    directives: {
        focus: {
            inserted: (el) => {
                Vue.nextTick(() => {
                    el.focus();
                })
            }
        }
    }
})
